#!/usr/bin/env node
import {EOL} from 'os';
import {writeFileSync} from 'fs';
import {dirname, basename, join} from 'path';
import {getUser, initDeezerApi, searchMusic} from 'd-fi-core';
import logUpdate from 'log-update';
import pMap from 'p-map';
import signale from './lib/signale';
import downloadTrack from './lib/download-track';
import parseInfo from './lib/parse-info';
import conf from './lib/config';

/**
 * Application init.
 */
export const initApp = async () => {
  logUpdate(signale.pending('Initializing session...'));
  const arl = conf.get('cookies.arl') as string;
  logUpdate(signale.pending('Verifying session...'));
  await initDeezerApi(arl);
  const {BLOG_NAME} = await getUser();
  logUpdate(signale.success('Logged in as ' + BLOG_NAME));
  logUpdate.done();
};

export const getTrackMetadata = async (url: string) => {
  const data = await parseInfo(url);
  if (!data) {
    throw new Error('Please provide a valid URL. Unknown URL: ' + url);
  }
  return Promise.resolve(data.tracks[0]);
};

export const searchTrack = async (query: string) => {
  const {TRACK} = await searchMusic(query, ['TRACK']);
  const data = {
    info: {type: 'track', id: query},
    linktype: 'track',
    linkinfo: {},
    tracks: TRACK.data,
  };

  return data;
};

export const startDownload = async (url: string, quality: '128' | '320' | 'flac', concurrency: number = 4) => {
  const saveLayout: any = conf.get('saveLayout');

  try {
    const data = await parseInfo(url);
    if (!data) {
      throw new Error('Please provide a valid URL. Unknown URL: ' + url);
    }
    console.log(data.tracks);
    if (data && data.tracks.length > 0) {
      console.log(signale.info(`Proceeding download of ${data.tracks.length} tracks. Be patient.`));
      let trackNumber = conf.get('trackNumber', true) as boolean;
      let m3u8: string[] = [];
      let savedFiles: string[] = [];

      await pMap(
        data.tracks,
        async (track, index) => {
          const savedPath = await downloadTrack({
            track,
            quality: quality,
            info: (data as any).linkinfo,
            path: saveLayout[(data as any).linktype],
            totalTracks: data ? data.tracks.length : 10,
            trackNumber,
            message: `(${index}/${(data as any).tracks.length})`,
          });
          if (savedPath) {
            m3u8.push(basename(savedPath));
            savedFiles.push(savedPath);
          }
        },
        {concurrency: concurrency},
      );
      if (m3u8.length > 0) {
        const playlistDir = dirname(savedFiles[0]);
        const playlistFile = join(playlistDir, basename(playlistDir) + '.m3u8');
        const m3u8Content = '#EXTM3U' + EOL + m3u8.sort().join(EOL);
        writeFileSync(playlistFile, m3u8Content, {encoding: 'utf-8'});
      }
    } else {
      console.log(signale.info('No items to download!'));
    }
  } catch (err) {
    console.error(signale.error(err.message));
  }
};
